package com.hc.kotlin

fun main() {
    //-----初始化-----
    var kc = KClassC("kotlin")
    println(kc.name)
    var kd = KClassD(18,"java")
    println(kd.age)
    var kd2 = KClassD(10)
    println(kd2.name)
    var ke = KClassE("javac")
    var f = Father("father")
    var s = Sun1()
    println(f is Father) //instance of
    println(s is Father)
    println(f is Sun1)
    println(s is Sun1)
    var s2 = Sun2("sun2")
    println(s2.name)
    var s3 = object :Sun2("singleton sun3"){ //object用法二 类似匿名内部类
        override fun f1() {
            println("singleton sun3 f1()")
        }
    }
    s3.f1()
}
class KClassC(name:String){ //主构造
    init { //初始化块在构造实例时执行
        println("i execute in build ")
    }
    var name = name //属性写在方法体中
        get() = field.capitalize()
}
class KClassD(var age:Int,name: String){ //主构造 属性直接写在构造中
    var name = name
    constructor(name: String):this(20,name)//次构造
    constructor(a:Int):this(a,"go"){ //次构造
        this.name = name.toUpperCase()
    }
}
class KClassE(_name:String,var age:Int){
    //-----初始化顺序-----主构造声明的属性-类级别属性-init属性和函数-次构造属性和函数
    var name = _name
    var addresss:String
    var score = 10
    init {
        addresss = "上海"
    }
    constructor(_name:String):this(_name,10){
        score = 20
    }
}
class KClassF(){
    lateinit var name:String //延迟初始化
    val age by lazy { //使用时初始化
        initAge()
    }

    private fun initAge():Int {
       return 20
    }

    fun initName(){
        name = "Hello"
    }
    fun printName(){
        if(::name.isInitialized){ //检查是否初始化
            println(name)
        }
    }
}
open class Father(name:String){
    open var name = name
    open fun f1(){
        println("Father f1()")
    }

}
class Sun1():Father("张三"){ //继承
    override fun f1() {
        println("Sun1 f1()")
    }
}
open class Sun2(override var name:String):Father(name){
    override fun f1() {
        println("Sun2 f1()")
    }
}
object SingletonObject{ //object用法一 单例对象
    init {
        println("i am singleton object")
    }
    fun f1(){
        println("singleton object f1()")
    }
}
class CompanionObject{
    companion object{ //object用法三 伴生对象 该对象是外部类的静态属性
        var sub = "companion object"
        fun read(){
            println(sub)
        }
    }
}
